package com.masonluo.mlonlinejudge.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author masonluo
 * @date 2020/12/27 3:24 下午
 */
public class EnumUtils {

    private static final Logger log = LoggerFactory.getLogger(EnumUtils.class);

    private EnumUtils() {

    }

    /**
     * 枚举类的通用方法，使用该方法需要枚举类包含着一个id的属性，可以根据这个id属性去找到枚举类的具体对象
     *
     * @param clazz 枚举类
     * @param id    枚举类的id
     */
    @SuppressWarnings("unchecked")
    public static <T extends Enum<T>> T getEnumById(Class<T> clazz, Integer id) {
        try {
            Method valuesMethod = clazz.getMethod("values");
            T[] members = (T[]) valuesMethod.invoke(null);
            for (T member : members) {
                Class<T> cla = (Class<T>) member.getClass();
                Method getId = cla.getMethod("getId");
                int targetId = (int) getId.invoke(member);
                if (Objects.equals(targetId, id)) {
                    return member;
                }
            }
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            log.debug("The enumeration type is lose some methods", e);
        }
        return null;
    }

    /**
     * 获取枚举类型的id属性
     */
    public static <T extends Enum<T>> Integer getEnumId(T obj) {
        try {
            Class<?> clazz = obj.getClass();
            Field idField = clazz.getField("id");
            idField.setAccessible(true);
            return idField.getInt(obj);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.debug("The enumeration type dose not has the id field", e);
        }
        return null;
    }
}
